package com.example.demo.concurrent.countDownLatch;

import lombok.extern.slf4j.Slf4j;
import org.springframework.core.task.support.ExecutorServiceAdapter;

import java.util.concurrent.*;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: sfx
 * Date: 2023-08-12
 * Time: 13:22
 */
@Slf4j(topic = "c.TestCountDownLatch")
public class TestCountDownLatch {
    private static final ExecutorService poll = Executors.newFixedThreadPool(4);
    private static final CountDownLatch latch = new CountDownLatch(3);


    static CyclicBarrier cyclicBarrier = new CyclicBarrier(2);


    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        executorService.submit(()->{
            try {
                log.debug("step1");
                cyclicBarrier.await();
                log.debug("step2");
                cyclicBarrier.await();
                log.debug("step3");
            } catch (InterruptedException | BrokenBarrierException e) {
                throw new RuntimeException(e);
            }
        });

        executorService.submit(()->{
            try {
                log.debug("step1");
                cyclicBarrier.await();
                log.debug("step2");
                cyclicBarrier.await();
                log.debug("step3");
            } catch (InterruptedException | BrokenBarrierException e) {
                throw new RuntimeException(e);
            }
        });
        executorService.shutdown();
    }


    public static void main2(String[] args) {
        for (int i = 0; i < 3; ++i) {
            poll.submit(() -> {
                log.debug("start...");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                latch.countDown();
                log.debug("end...");
            });
            poll.submit(() -> {
                log.debug("start...");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                latch.countDown();
                log.debug("end...");
            });

        }
        try {
            latch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        poll.shutdownNow();
        log.debug("wait end...");
    }

    public static void main1(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(3);
        new Thread(() -> {
            log.debug("start...");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            latch.countDown();
            log.debug("end...");
        }, "t1").start();

        new Thread(() -> {
            log.debug("start...");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            latch.countDown();
            log.debug("end...");
        }, "t2").start();

        new Thread(() -> {
            log.debug("start...");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            latch.countDown();
            log.debug("end...");
        }, "t3").start();

        latch.await();
        log.debug("wait end...");
    }
}